﻿using System;
using System.Threading;
using Emgu.CV;
using Emgu.CV.Structure;

namespace Projekt_naczepa
{
    public class RemoteCamera
    {
        private UDPConnection connection;
        private bool isNewFrame;
        private Thread thread_;
        private Mutex mutex_;

        //    public delegate void onCommand(Command cmd);
     //   public delegate void onFrameDownloadDone();
   //     public delegate void onFrameDGram();

        //  private onCommand           callback_onCommand=null;
   //     private onFrameDGram callback_onFrameDGram = null;
    //    private onFrameDownloadDone callback_onFrameDownload = null;

            public Image<Bgr, byte> recived_frame;

        public const int S_NO_TRANSFER = 0x01;
        public const int S_FRAME_AVAILABLE = 0x02;
        public const int S_FRAME_TRANSFER = 0x04;

        public int State = S_NO_TRANSFER;

        public RemoteCamera()
        {
            connection = new UDPConnection();
            isNewFrame = false;
                   recived_frame = new Image<Bgr,byte>(new System.Drawing.Size(640,480));

            mutex_ = new Mutex();
            thread_ = new Thread(new ThreadStart(this.cameraThread));
            
        }
        public bool connectCamera(string addr, int port)
        {
            thread_.Start();
            if (connection.connect(addr, port) == true) return true;
            if (connection.sendHello() == true) return true;
            return false;
        }
        public void disconnectCamera()
        {
            connection.disconnect();
            thread_.Abort();
        }
        public bool sendLuaCommand(string cmd)
        {
            return connection.sendCommand(UDPConnection.LUA, cmd);
        }
        public bool startCamera(string name)
        {
            return sendLuaCommand("startCamera(\"" + name + "\")");
        }
        public bool stopCamera(string name)
        {
            return sendLuaCommand("stopCamera(\"" + name + "\")");
        }
        public bool queryFrame(string name, int frames = 15)
        {
            isNewFrame = false;
            return sendLuaCommand("sendFrame(\"" + name + "\"," + frames.ToString() + ")");
        }
        public bool halatServer()
        {
            return connection.sendCommand(UDPConnection.INTERNAL, "halt_server");
        }
       
        public bool isFrameAvailable() { return isNewFrame; }
             public Image<Bgr, byte> getFrame()
             {
                 return recived_frame;
             }
          
        /*public void setCallBack(/*onCommand on_cmd, onFrameDGram on_fdg, onFrameDownloadDone on_fd)
        {
            // callback_onCommand          = on_cmd;
            callback_onFrameDGram = on_fdg;
            callback_onFrameDownload = on_fd;
        }*/
        public float getProgress() { return connection.progress; }
        private void cameraThread()
        {
            CommandTranslator translator = new CommandTranslator();
            while (true)
            {
                Command cmd = connection.getCommand();
                if (cmd == null) continue;
                translator.translate(cmd);
           //     if (cmd.cmd == UDPConnection.IMAGE_DATA && callback_onFrameDGram != null)
         //           callback_onFrameDGram();
                if (cmd.cmd == UDPConnection.IMAGE_START)
                {
                    State = S_FRAME_TRANSFER;
                    if (translator.isPNG() > 0)
                        System.Console.WriteLine("PNG :D");
                }
                if (cmd.cmd == UDPConnection.IMAGE_STOP)
                {
                                    for (int x = 0; x < 640; x++)
                                        for (int y = 0; y < 480; y++)
                                        {
                                            recived_frame.Data[y, x,0]  = connection.image_data[(x + (y * 640))*3 + 0];
                                            recived_frame.Data[y, x, 1] = connection.image_data[(x + (y * 640))*3 + 1];
                                            recived_frame.Data[y, x, 2] = connection.image_data[(x + (y * 640))*3 + 2];
                                        }
                      
                    isNewFrame = true;
                //    if (callback_onFrameDownload != null) callback_onFrameDownload();
                    State = S_NO_TRANSFER | S_FRAME_AVAILABLE;
                    sendLuaCommand(";");
                }
            }
        }
    }
}

